<?php

/**
 * 文件上传类
 * 
 * @package    01CMS
 * @subpackage system
 * @author     rolong at vip.qq.com
 * @version    1.0.0
 * @link       http://www.01cms.com
 */

class Upload
{
    
    public $maxSize = 0;
    public $maxWidth = 0;
    public $maxHeight = 0;
    public $allowedTypes = "";
    public $fileTemp = "";
    public $fileName = "";
    public $origName = "";
    public $fileType = "";
    public $fileSize = "";
    public $fileExt = "";
    public $uploadPath = "";
    public $overwrite = FALSE;
    public $isImage = FALSE;
    public $imageWidth = '';
    public $imageHeight = '';
    public $imageType = '';
    public $imageSizeStr = '';
    public $errorMsg = '';
    public $mimes = array();
    public $removeSpaces = TRUE;
    public $tempPrefix = "temp_file_";

    function initialize ($config = array())
    {
        $defaults = array('maxSize'=>0, 'maxWidth'=>0, 'maxHeight'=>0, 'allowedTypes'=>"", 'fileTemp'=>"", 'fileName'=>"", 'origName'=>"", 'fileType'=>"", 'fileSize'=>"", 'fileExt'=>"", 'uploadPath'=>"", 'overwrite'=>FALSE, 'encryptName'=>FALSE, 'isImage'=>FALSE, 'imageWidth'=>'', 'imageHeight'=>'', 'imageType'=>'', 'imageSizeStr'=>'', 'errorMsg'=>'', 'mimes'=>array(), 'removeSpaces'=>TRUE, 'xssClean'=>FALSE, 'tempPrefix'=>"temp_file_");
        
        foreach ($defaults as $key => $val)
        {
            if (isset($config[$key]))
            {
                $method = 'set' . ucfirst($key);
                
                if (method_exists($this, $method))
                {
                    $this->$method($config[$key]);
                }
                else
                {
                    $this->$key = $config[$key];
                }
            }
            else
            {
                $this->$key = $val;
            }
        }
    }

    function doUpload ($field = 'userfile')
    {
        if (! isset($_FILES[$field]))
        {
            $this->setError('您还没有选择要上传的文件');
            return FALSE;
        }
        
        if (! $this->validateUploadPath())
        {
            return FALSE;
        }
        
        if (! is_uploaded_file($_FILES[$field]['tmp_name']))
        {
            $error = (! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
            
            switch ($error)
            {
                case 1:
                $this->setError('文件大小超过了最大限制');
                break;
                case 2:
                $this->setError('文件大小超过了最大限制');
                break;
                case 3:
                $this->setError('文件未全部上传');
                break;
                case 4:
                $this->setError('您还没有选择要上传的文件');
                break;
                case 6:
                $this->setError('临时目录不存在');
                break;
                case 7:
                $this->setError('文件不可写');
                break;
                default:
                $this->setError('找不到文件');
                break;
            }
            
            return FALSE;
        }
        
        $this->fileTemp = $_FILES[$field]['tmp_name'];
        //$this->fileName = $_FILES[$field]['name'];
        $this->fileSize = $_FILES[$field]['size'];
        $this->fileType = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
        $this->fileType = strtolower($this->fileType);
        $this->fileExt = $this->getExtension($_FILES[$field]['name']);
        
        if ($this->fileSize > 0)
        {
            $this->fileSize = round($this->fileSize / 1024, 2);
        }
        
        if (! $this->isAllowedFiletype())
        {
            $this->setError('禁止上传的文件类型');
            return FALSE;
        }
        
        if (! $this->isAllowedFilesize())
        {
            $this->setError('文件大小超过了最大限');
            return FALSE;
        }
        
        $this->fileName = $this->getFileName();
        
        if (! @copy($this->fileTemp, $this->uploadPath . $this->fileName))
        {
            if (! @move_uploaded_file($this->fileTemp, $this->uploadPath . $this->fileName))
            {
                $this->setError('upload_destination_error');
                return FALSE;
            }
        }
        
        $this->setImageProperties($this->uploadPath . $this->fileName);
        
        return TRUE;
    }

    function data ()
    {
        return array('fileName'=>$this->fileName, 'fileType'=>$this->fileType, 'file_path'=>$this->uploadPath, 'fullPath'=>$this->uploadPath . $this->fileName, 'rawName'=>str_replace($this->fileExt, '', $this->fileName), 'origName'=>$this->origName, 'fileExt'=>$this->fileExt, 'fileSize'=>$this->fileSize, 'isImage'=>$this->isImage(), 'imageWidth'=>$this->imageWidth, 'imageHeight'=>$this->imageHeight, 'imageType'=>$this->imageType, 'imageSizeStr'=>$this->imageSizeStr);
    }

    function setUploadPath ($path)
    {
        // Make sure it has a trailing slash
        $this->uploadPath = rtrim($path, '/') . '/';
    }

    function getFileName ()
    {
        if ($this->fileName == '')
        {
            $this->fileName = date('YmdHis') . mt_rand(100, 999);
        }
        return $this->fileName . '.' . $this->fileExt;
    }

    function setFileName ($fileName)
    {
        $this->fileName = $fileName;
    }

    function setMaxFilesize ($n)
    {
        $this->maxSize = ((int) $n < 0) ? 0 : (int) $n;
    }

    function setMaxWidth ($n)
    {
        $this->maxWidth = ((int) $n < 0) ? 0 : (int) $n;
    }

    function setMaxHeight ($n)
    {
        $this->maxHeight = ((int) $n < 0) ? 0 : (int) $n;
    }

    function setAllowedTypes ($types)
    {
        $this->allowedTypes = explode('|', $types);
    }

    function setImageProperties ($path = '')
    {
        if (! $this->isImage())
        {
            return;
        }
        
        if (function_exists('getimagesize'))
        {
            if (FALSE !== ($D = @getimagesize($path)))
            {
                $types = array(1=>'gif', 2=>'jpeg', 3=>'png');
                
                $this->image_width = $D['0'];
                $this->image_height = $D['1'];
                $this->imageType = (! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
                $this->imageSizeStr = $D['3'];
            }
        }
    }

    function isImage ()
    {
        $imgType = array('gif', 'jpeg', 'png', 'jpg');
        
        return (in_array(strtolower($this->fileExt), $imgType)) ? TRUE : FALSE;
    }

    function isAllowedFiletype ()
    {
        if (count($this->allowedTypes) == 0 or ! is_array($this->allowedTypes))
        {
            $this->setError('没有设置允许上传的文件类型');
            return FALSE;
        }
        
        if (in_array(strtolower($this->fileExt), $this->allowedTypes))
        {
            return TRUE;
        }
        
        return FALSE;
    }

    function isAllowedFilesize ()
    {
        if ($this->maxSize != 0 and $this->fileSize > $this->maxSize)
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

    function validateUploadPath ()
    {
        if ($this->uploadPath == '')
        {
            $this->setError('没有设置文件保存路径');
            return FALSE;
        }
        
        if (function_exists('realpath') and @realpath($this->uploadPath) !== FALSE)
        {
            $this->uploadPath = str_replace("\\", "/", realpath($this->uploadPath));
        }
        
        if (! @is_dir($this->uploadPath))
        {
            $this->setError('文件保存路径不是一个目录');
            return FALSE;
        }
        
        if (! is_writable($this->uploadPath))
        {
            $this->setError('文件保存路径不可写');
            return FALSE;
        }
        
        $this->uploadPath = preg_replace('/(.+?)\/*$/', "\\1/", $this->uploadPath);
        return TRUE;
    }

    function getExtension ($filename)
    {
        $x = explode('.', $filename);
        return end($x);
    }

    function setError ($msg)
    {
        if (is_array($msg))
        {
            foreach ($msg as $val)
            {
                $this->errorMsg .= ' ' . $val;
            }
        }
        else
        {
            $this->errorMsg = $msg;
        }
    }

}

// END Upload Class
